package io.renren.common.utils;

import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Clock;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.Calendar;
import java.util.Date;

/**
 * @author Singer create by Singer email:313402703@qq.com
 * @Title: MyDateTest
 * @ProjectName xulcor-account-platform
 * @Description: TODO
 * @date 2018/11/12 15:36
 */

public class MyDateTest {


    /**
     *
     * @description: 拿到下次付款时间
     * @auther: create by Singer - 王 浩 email:313402703@qq.com
     * @date 2018/11/14 19:57
     * @param
     * @return
     */
    public Long calNextPayDay(LocalDateTime time,Integer month){

        Long nextTime = Long.valueOf(0); //下个时间

        Integer currentTimeYear = time.getYear(); //当前时间的年份

        Integer currentTimeMonth = time.getMonthValue(); //当前时间的月份

        Integer currentTimeDay = time.getDayOfMonth(); //当天时间的天数 -> ofMonth

        //拿到当前时间有多少天
        Integer totalDayOfCurrentTime = time.with(TemporalAdjusters.lastDayOfMonth()).getDayOfMonth();

        //当前时间月份+分期月份=timeMonth 为下面判断是否跨年做准备
        Integer timeMonth = BigInteger.valueOf(month.longValue()).add(BigInteger.valueOf(currentTimeMonth.longValue())).intValue();

        //判断是否跨年
        if(timeMonth.compareTo(Integer.valueOf(12)) > 0) {

            //除法,取整 重置当前年份
            currentTimeYear = BigDecimal.valueOf(currentTimeYear.longValue()).add(BigDecimal.valueOf(timeMonth.longValue()).divideToIntegralValue(BigDecimal.valueOf(12))).intValue();

            //重置timeMonth
            timeMonth = BigDecimal.valueOf(timeMonth.longValue()).subtract(BigDecimal.valueOf(timeMonth.longValue()).divideToIntegralValue(BigDecimal.valueOf(12)).setScale(0, BigDecimal.ROUND_DOWN).multiply(BigDecimal.valueOf(12))).intValue();

            //重新计算,纠错
            if (timeMonth.compareTo(BigInteger.ZERO.intValue()) == 0) {
                currentTimeYear = BigDecimal.valueOf(currentTimeYear.longValue()).subtract(BigDecimal.ONE).setScale(0, BigDecimal.ROUND_DOWN).intValue();
                timeMonth = 12;
            }
        }
            Integer lastDay = LocalDateTime.of(currentTimeYear,timeMonth,1,0,0,0).with(TemporalAdjusters.lastDayOfMonth()).getDayOfMonth();


            if(currentTimeDay.compareTo(totalDayOfCurrentTime) == 0 || currentTimeDay.compareTo(lastDay) > 0){
                nextTime = LocalDateTime.of(currentTimeYear, timeMonth, lastDay, 0, 0, 0).atZone(Clock.systemDefaultZone().getZone()).toInstant().getEpochSecond();
            }else{
                if(BigDecimal.valueOf(lastDay.longValue()).subtract(BigDecimal.valueOf(currentTimeDay.longValue())).compareTo(BigDecimal.valueOf(4)) < 0){
                    Integer value = BigDecimal.valueOf(lastDay.longValue()).subtract(BigDecimal.valueOf(lastDay.longValue()).subtract(BigDecimal.valueOf(currentTimeDay.longValue()).abs())).intValue();
                    nextTime = LocalDateTime.of(currentTimeYear, timeMonth, value, 0, 0, 0).atZone(Clock.systemDefaultZone().getZone()).toInstant().getEpochSecond();
                }else{
                    nextTime = time.plus(month, ChronoUnit.MONTHS).atZone(Clock.systemDefaultZone().getZone()).toInstant().getEpochSecond();
                }
            }

        //最终的时间要减去一天
        nextTime = LocalDateTime.ofInstant(Instant.ofEpochSecond(nextTime),Clock.systemDefaultZone().getZone()).minus(1, ChronoUnit.DAYS).atZone(Clock.systemDefaultZone().getZone()).toEpochSecond();
        return nextTime;
    }

    public static void main(String[] args) {
        //
        Integer currentTimeYear = BigDecimal.valueOf(32L).divideToIntegralValue(BigDecimal.valueOf(12)).intValue();
        System.out.println(currentTimeYear);
    }

    /**
     * 获取计下次付款时间
     *
     * @param date
     * @param month
     * @return
     * @throws ParseException
     * @author yzx
     */
    public int getNexDay(String date, int month) {
        //字符串时间转换为date
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date stdata = null;
        try {
            stdata = simpleDateFormat.parse(date);
        } catch (Exception e) {
            e.printStackTrace();
        }

        LocalDate parse = LocalDate.parse(date);

        //当前月最后一天
        //int next_last_day = this.getMaxMonthDate(stdata);
        //int next_last_day = LocalDateTime.from(stdata.toInstant()).atZone(Clock.systemDefaultZone().getZone()).with(TemporalAdjusters.lastDayOfMonth()).getDayOfMonth();
        int next_last_day = LocalDate.parse(date).with(TemporalAdjusters.lastDayOfMonth()).getDayOfMonth();

        Calendar cal = Calendar.getInstance();
        cal.setTime(stdata);

        int time_year = cal.get(Calendar.YEAR);
        int time_month = cal.get(Calendar.MONTH) + 1;
        int time_day = cal.get(Calendar.DATE) - 1;
        int next_time_month = time_month + 1;

        if (next_time_month > 12) {
            time_year = time_year + next_time_month / 12;
            next_time_month = next_time_month - next_time_month / 12 * 12;
            if (next_time_month == 0) {
                time_year--;
                next_time_month = 12;
            }
        }
        //下一个月最后一天时间
        //int last_day = this.getLaseMonth(stdata);
        int last_day = LocalDate.parse(date).plus(1,ChronoUnit.MONTHS).with(TemporalAdjusters.lastDayOfMonth()).getDayOfMonth();

        int next_time = 0;

        // 判断是否是月底最后一天， 或第一个月的最后一天大于下一个月最后一天
        try {
            if (time_day == next_last_day || time_day > last_day) {
                String data_str = time_year + "-" + next_time_month + "-" + time_day;
                next_time = (int) (simpleDateFormat.parse(data_str).getTime() / 1000);
            } else if ((last_day - time_day) < 4) {
                last_day = last_day - Math.abs(last_day - time_day);
                String data_str = time_year + "-" + next_time_month + "-" + time_day;
                next_time = (int) (simpleDateFormat.parse(data_str).getTime() / 1000);
            } else {
                cal.add(Calendar.MONTH, month);
                String data_str = simpleDateFormat.format(cal.getTime());
                next_time = (int) (simpleDateFormat.parse(data_str).getTime() / 1000);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return next_time;
    }

    /**
     * 判断当天是否为本月第一天
     *
     * @return
     */
    public boolean isFirstDayOfMonth() {
        boolean flag = false;
        Calendar calendar = Calendar.getInstance();
        int today = calendar.get(calendar.DAY_OF_MONTH);
        if (1 == today) {
            flag = true;
        }
        return flag;
    }

    /**
     * 获取当前月份最后一天
     *
     * @param date
     * @return
     * @throws ParseException
     */
    public int getMaxMonthDate(Date date) {
        SimpleDateFormat dft = new SimpleDateFormat("yyyyMMdd");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        // calendar.add(Calendar.MONTH, -1);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        int time_day = calendar.get(Calendar.DATE) - 1;
        return time_day + 1;
//        return dft.format(calendar.getTime());
    }

    /**
     * 描述:获取下一个月的第一天.
     *
     * @return
     */
    public String getPerFirstDayOfMonth(Date date) {
        SimpleDateFormat dft = new SimpleDateFormat("yyyyMMdd");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, 1);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
        return dft.format(calendar.getTime());
    }

    /**
     * 描述:获取上个月的最后一天.
     *
     * @return
     */
    public String getLastMaxMonthDate(Date date) {
        SimpleDateFormat dft = new SimpleDateFormat("yyyyMMdd");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, -1);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        return dft.format(calendar.getTime());
    }

    /**
     * 获取上一个月
     *
     * @return
     */
    public String getLastMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(cal.MONTH, -1);
        SimpleDateFormat dft = new SimpleDateFormat("yyyyMM");
        String lastMonth = dft.format(cal.getTime());
        return lastMonth;
    }

    /**
     * 描述:获取下一个月.
     *
     * @return
     */
    public String getPreMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(cal.MONTH, 1);
        SimpleDateFormat dft = new SimpleDateFormat("yyyyMM");
        String preMonth = dft.format(cal.getTime());
        return preMonth;
    }


    /**
     * 获取任意时间的下一个月
     * 描述:<描述函数实现的功能>.
     *
     * @param repeatDate
     * @return
     */
    public String getPreMonth(String repeatDate) {
        String lastMonth = "";
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat dft = new SimpleDateFormat("yyyyMM");
        int year = Integer.parseInt(repeatDate.substring(0, 4));
        String monthsString = repeatDate.substring(4, 6);
        int month;
        if ("0".equals(monthsString.substring(0, 1))) {
            month = Integer.parseInt(monthsString.substring(1, 2));
        } else {
            month = Integer.parseInt(monthsString.substring(0, 2));
        }
        cal.set(year, month, Calendar.DATE);
        lastMonth = dft.format(cal.getTime());
        return lastMonth;
    }

    /**
     * 获取任意时间的上一个月
     * 描述:<描述函数实现的功能>.
     *
     * @param repeatDate
     * @return
     */
    public static String getLastMonth(String repeatDate) {
        String lastMonth = "";
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat dft = new SimpleDateFormat("yyyyMM");
        int year = Integer.parseInt(repeatDate.substring(0, 4));
        String monthsString = repeatDate.substring(4, 6);
        int month;
        if ("0".equals(monthsString.substring(0, 1))) {
            month = Integer.parseInt(monthsString.substring(1, 2));
        } else {
            month = Integer.parseInt(monthsString.substring(0, 2));
        }
        cal.set(year, month - 2, Calendar.DATE);
        lastMonth = dft.format(cal.getTime());
        return lastMonth;
    }





    /**
     * 获取任意时间的月的最后一天
     * 描述:<描述函数实现的功能>.
     *
     * @param repeatDate
     * @return
     */
    private static String getMaxMonthDate(String repeatDate) {
        SimpleDateFormat dft = new SimpleDateFormat("yyyyMMdd");
        Calendar calendar = Calendar.getInstance();
        try {
            if (StringUtils.isEmpty(repeatDate) && !"null".equals(repeatDate)) {
                calendar.setTime(dft.parse(repeatDate));
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        // calendar.add(Calendar.MONTH, -1);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        System.out.println();
        return dft.format(calendar.getTime());
    }

    /**
     * 获取任意时间的月第一天
     * 描述:<描述函数实现的功能>.
     *
     * @param repeatDate
     * @return
     */
    private static String getMinMonthDate(String repeatDate) {
        SimpleDateFormat dft = new SimpleDateFormat("yyyyMMdd");
        Calendar calendar = Calendar.getInstance();
        try {
            if (StringUtils.isEmpty(repeatDate) && !"null".equals(repeatDate)) {
                calendar.setTime(dft.parse(repeatDate));
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        // calendar.add(Calendar.MONTH, -1);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
        return dft.format(calendar.getTime());
    }

    /**
     * 不论是当前时间，还是历史时间  皆是时间点的前天
     * repeatDate  任意时间
     */
    public String getModify2DaysAgo(String repeatDate) {
        Calendar cal = Calendar.getInstance();
        String daysAgo = "";
        SimpleDateFormat dft = new SimpleDateFormat("yyyyMMdd");
        if (repeatDate == null || "".equals(repeatDate)) {
            cal.set(Calendar.DATE, cal.get(Calendar.DATE) - 2);

        } else {
            int year = Integer.parseInt(repeatDate.substring(0, 4));
            String monthsString = repeatDate.substring(4, 6);
            int month;
            if ("0".equals(monthsString.substring(0, 1))) {
                month = Integer.parseInt(monthsString.substring(1, 2));
            } else {
                month = Integer.parseInt(monthsString.substring(0, 2));
            }
            String dateString = repeatDate.substring(6, 8);
            int date;
            if ("0".equals(dateString.subSequence(0, 1))) {
                date = Integer.parseInt(dateString.substring(1, 2));
            } else {
                date = Integer.parseInt(dateString.substring(0, 2));
            }
            cal.set(year, month - 1, date - 1);
            System.out.println(dft.format(cal.getTime()));
        }
        daysAgo = dft.format(cal.getTime());
        return daysAgo;
    }

    /**
     * 不论是当前时间，还是历史时间  皆是时间点的T-N天
     * repeatDate 任意时间    param 数字 可以表示前几天
     */
    public String getModifyNumDaysAgo(String repeatDate, int param) {
        Calendar cal = Calendar.getInstance();
        String daysAgo = "";
        SimpleDateFormat dft = new SimpleDateFormat("yyyyMMdd");
        if (repeatDate == null || "".equals(repeatDate)) {
            cal.set(Calendar.DATE, cal.get(Calendar.DATE) - param);

        } else {
            int year = Integer.parseInt(repeatDate.substring(0, 4));
            String monthsString = repeatDate.substring(4, 6);
            int month;
            if ("0".equals(monthsString.substring(0, 1))) {
                month = Integer.parseInt(monthsString.substring(1, 2));
            } else {
                month = Integer.parseInt(monthsString.substring(0, 2));
            }
            String dateString = repeatDate.substring(6, 8);
            int date;
            if ("0".equals(dateString.subSequence(0, 1))) {
                date = Integer.parseInt(dateString.substring(1, 2));
            } else {
                date = Integer.parseInt(dateString.substring(0, 2));
            }
            cal.set(year, month - 1, date - param + 1);
            System.out.println(dft.format(cal.getTime()));
        }
        daysAgo = dft.format(cal.getTime());
        return daysAgo;
    }

    /**
     * 获取下个月的最后一天
     *
     * @param date
     * @return
     */
    public int getLaseMonth(Date date) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, 2);
        calendar.set(Calendar.DATE, 0);
        return calendar.get(Calendar.DATE);
//        return df.format(calendar.getTime());
    }

    /**
     * 获取时间戳
     *
     * @param data_str
     * @return
     */
    public static int date2TimestampSecond(String data_str, String dataType) {

        SimpleDateFormat simpleDateFormat = null;
        if (StringUtils.isEmpty(dataType)) {
            simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        } else {
            simpleDateFormat = new SimpleDateFormat(dataType);
        }

        int next_time = 0;
        try {
            next_time = (int) (simpleDateFormat.parse(data_str).getTime() / 1000);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return next_time;
    }


    /**
     * 时间戳转换成日期格式字符串
     *
     * @param seconds 精确到秒的字符串
     * @param format
     * @return
     */
    public static String timeStamp2Date(int seconds, String format) {
        if (seconds <= 0) {
            return "";
        }
        String seconds_str = String.valueOf(seconds);
        if (format == null || format.isEmpty()) {
            format = "yyyy-MM-dd";
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(new Date(Long.valueOf(seconds_str + "000")));
    }

    /**
     * @return java.lang.String
     * @author Lcc
     * @Desc 时间戳获取方法，false 获取10 位，true 获取13位时间戳
     * @version 2018/6/19 上午11:08
     * @Param [msecTimestamp]
     **/
    public static String getTimestamp(Boolean msecTimestamp) {
        String timestamp = String.valueOf(new Date().getTime());
        if (!msecTimestamp) {
            timestamp = timestamp.substring(0, timestamp.length() - 3);
        }
        return timestamp;
    }

}
